﻿using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Casamiel.API.Application.Models;
using Casamiel.API.Application.Services;
using Casamiel.Application;
using Casamiel.Common;
using Casamiel.Domain.Entity;
using Enyim.Caching;
using MediatR;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;

namespace Casamiel.API.Application.Commands
{
    /// <summary>
    /// 
    /// </summary>
    public class CreatePaymentRequestCommandHandler : IRequestHandler<CreatePaymentRequestCommand, BasePaymentRsp>
    {
        private readonly NLog.ILogger logger = NLog.LogManager.GetLogger("MallService");
        private readonly IPaymentService _paymentService;
        private readonly IPayGateWayService _gateways;
        private readonly IWxService _wxLogin;
        private readonly IMemcachedClient _memcachedClient;
        private readonly string _memcachedPre;
        private readonly IIcApiService _icApiService;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="iicApiService"></param>
        /// <param name="paymentService"></param>
        /// <param name="payGateWayService"></param>
        /// <param name="wxService"></param>
        /// <param name="snapshot"></param>
        /// <param name="memcachedClient"></param>
        public CreatePaymentRequestCommandHandler(IIcApiService iicApiService, IPaymentService paymentService, IPayGateWayService payGateWayService,
             IOptionsSnapshot<CasamielSettings> snapshot, IWxService wxService, IMemcachedClient memcachedClient)
        {
            if (snapshot == null) {
                throw new ArgumentNullException(nameof(snapshot));
            }

            _paymentService = paymentService;
            _gateways = payGateWayService;
            _wxLogin = wxService;
            _memcachedClient = memcachedClient;
            _memcachedPre = snapshot.Value.MemcachedPre;
            _icApiService = iicApiService;

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<BasePaymentRsp> Handle(CreatePaymentRequestCommand request, CancellationToken cancellationToken)
        {
            if (request == null) {
                throw new ArgumentNullException(nameof(request));
            }
            var _cachekey = _memcachedPre+Constant.PAYREQUESTTRADENO+ request.PaymentInfo.TradeNo;
            var result = new BasePaymentRsp();
            var payment = request.PaymentInfo;
            var trynum = _memcachedClient.Increment(_cachekey, 1, 1);
            
            result.Ordercode = payment.BillNO;
            result.Payed = false;
            result.PayMethod = $"{payment.PayMethod}";

            if (trynum > 1) {
                var rsp = await _memcachedClient.GetAsync<BasePaymentRsp>(_memcachedPre+Constant.PAYREQUEST + request.PaymentInfo.TradeNo);
                if (rsp.Success) {
                    return rsp.Value;
                }

                return result;

            }
            // var shopno = "";
            //switch (request.PaymentInfo.OperationMethod)
            //{
            //    case 2:
            //    case 4:
            //        var shopinfo = await _paymentService.GetShopIdAndShopNameByBillNOAsync<ICasaMielSession>(result.Ordercode);
            //        payment.ShopName = shopinfo.Item2;
            //        payment.ShopId = shopinfo.Item1;

            //        break;
            //    default:
            //        break;
            //}

            switch (request.PaymentInfo.PayMethod) {
                case (int)PayMethod.WechatPayApp:

                    payment.Remark = "app微信支付";
                    result.Paymentrequest = _gateways.CreateWechatpayOrder(payment.TradeNo, payment.Amount, payment.ShopName, payment.ShopNO);
                    break;

                case (int)PayMethod.Alipay:

                    payment.Remark = "app支付宝支付";
                    result.Paymentrequest = _gateways.CreateAlipayOrder(payment.TradeNo, payment.Amount, payment.ShopName, payment.ShopNO);
                    break;

                case (int)PayMethod.WechatMiniPay:

                    WxOpenId wxloginentity = null;

                    if (request.Id > 0) {
                        wxloginentity = await _wxLogin.GetByIdAsync<ICasaMielSession>(request.Id).ConfigureAwait(false);
                    } else {
                        var list = await _wxLogin.GetMiniAppSettingsList<ICasaMielSession>().ConfigureAwait(false);
                        var item = list.Find(c => c.Sort == (int)request.PaymentScenario);
                        if (item != null) {
                            wxloginentity = await _wxLogin.GetByAppIdMobileAsync<ICasaMielSession>(item.AppId, request.PaymentInfo.Mobile).ConfigureAwait(false);
                        }
                    }
                    //if (request.PaymentInfo.Mobile == "18605888772") {
                    //    var list = await _wxLogin.GetMiniAppSettingsList<ICasaMielSession>().ConfigureAwait(false);

                    //    var item = list.Find(c => c.Sort == (int)request.PaymentScenario);
                    //    logger.Trace("234:" + JsonConvert.SerializeObject(item));
                    //    if (item != null) {
                    //        wxloginentity = await _wxLogin.GetByAppIdMobileAsync<ICasaMielSession>(item.AppId, request.PaymentInfo.Mobile).ConfigureAwait(false);
                    //    }
                    //}
                    if (wxloginentity == null) {
                        throw new ArgumentException("openid不存在");
                    }
                    //payment.PayMethod = 4;
                    payment.Remark = "小程序微信支付";
                    //await _paymentService.AddAsync<ICasaMielSession>(payment);
                    //logger.Trace(JsonConvert.SerializeObject(wxloginentity));
                    result.Paymentrequest = _gateways.CreateMiniWechatpayOrder(payment.TradeNo, payment.Amount, wxloginentity.OpenId, wxloginentity.AppId,
                        payment.ShopName, payment.ShopNO, DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss", CultureInfo.CurrentCulture));

                    break;
                default:
                    break;
            }
            await _paymentService.AddAsync<ICasaMielSession>(payment).ConfigureAwait(false);
            await _memcachedClient.SetAsync(_memcachedPre+Constant.PAYREQUEST+request.PaymentInfo.TradeNo, result, 200);
            return result;
        }
    }
}
